home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / C and C++ / GNU Chess 3.0 / Sources TC 4.0 / mac.c < prev    next >
Text File  |  1991-04-23  |  32KB  |  1,509 lines

  1. /*
  2.   Mac interface for GNU Chess
  3.  
  4.   Revision: 10 Feb 1991
  5.  
  6.   Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
  7.   Copyright (c) 1991  Airy ANDRE
  8.  
  9.     expanded game save, list, and restore features
  10.     optional auto-updating of positional information
  11.  
  12.   This file is part of CHESS.
  13.  
  14.   CHESS is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY.  No author or distributor
  16.   accepts responsibility to anyone for the consequences of using it
  17.   or for whether it serves any particular purpose or works at all,
  18.   unless he says so in writing.  Refer to the CHESS General Public
  19.   License for full details.
  20.  
  21.   Everyone is granted permission to copy, modify and redistribute
  22.   CHESS, but only under the conditions described in the
  23.   CHESS General Public License.   A copy of this license is
  24.   supposed to have been given to you along with CHESS so you
  25.   can know your rights and responsibilities.  It should be in a
  26.   file named COPYING.  Among other things, the copyright notice
  27.   and this notice must be preserved on all copies.
  28.   */
  29.  
  30. #include <stdio.h>
  31. #include <DragMgr.h>
  32. #include <pascal.h>
  33. #include <SANE.h>
  34. #include "math.h"
  35.  
  36. #include "gnuchess.h"
  37. #include "macintf.h"
  38. #include "rsrc.h"
  39.  
  40.  
  41. char mvstr[5][6];
  42. long evrate;
  43.  
  44. short PositionFlag = 0;
  45. short coords = 1;
  46. short stars = 0;
  47. short rv = 1;
  48. short shade = 0;
  49. short preview = 0;
  50. short idoit = 0;
  51. short drawn = 0;
  52. short undo = 0;
  53. short anim = 1;
  54. short showvalue = 0;
  55. short newgame = 0;
  56. short getgame = 0;
  57. short wne;
  58.  
  59. char buff[100];
  60.  
  61. Boolean    Finished;
  62. CursHandle    ClockCursor;
  63. CursHandle    ArrowCursor;
  64. CursHandle    CrossCursor;
  65. Rect    DragArea;
  66. Rect    GrowArea;
  67. MenuHandle    Menu;
  68. WindowPtr    WindBoard, WindList, WindThink;
  69. int    width,height;
  70.  
  71. short background = 0;
  72.  
  73. Point    thePoint;
  74. Rect    MinSize;
  75.     
  76. Rect    nameRec, ValueRec, ValueFRec,chessRectOff;
  77.  
  78. Rect    MsgRec, MsgFRec;
  79. Rect    ThinkRec[2], ThinkFRec[2];
  80. Rect     ScoreRec, ScoreFRec;
  81.  
  82. int     theScore;
  83. Str255    Msg;
  84.  
  85. Str255    ThinkMove[2][30];
  86. int        maxThink;
  87.  
  88. DragHandle    myDragStuff;
  89. Point    pt;
  90.  
  91. Pattern blackPat, whitePat;
  92.  
  93. Rect    CaseRec, CaseFRec;
  94. int        MouseX, MouseY;
  95.  
  96. int     ref;
  97. long    nbre;
  98.  
  99. short saveBoard[64], saveColor[64];
  100.  
  101. int towho;
  102.  
  103. ListHandle List;
  104. Rect theBar;
  105.  
  106.  
  107. void SetUpThing(void)
  108. {    
  109.     int typ,err,i,j;
  110.     Handle Hitem;
  111.     Rect r;
  112.  
  113.     FlushEvents(everyEvent,0);
  114.  
  115.     MoreMasters();
  116.     MoreMasters();
  117.     MoreMasters();
  118.     MoreMasters();
  119.     MoreMasters();
  120.     MaxApplZone();
  121.  
  122.     InitGraf(&thePort);
  123.     InitFonts();
  124.     InitWindows();
  125.     InitMenus();
  126.     TEInit();
  127.     InitDialogs(0L);
  128.  
  129.     ClockCursor=GetCursor(watchCursor);
  130.     ArrowCursor=GetCursor(1000);
  131.     HNoPurge((Handle)ClockCursor);
  132.     HNoPurge((Handle)ArrowCursor);
  133.     SetCursor(*ClockCursor);
  134.     
  135.     StuffHex(blackPat, "\pFFFFFFFFFFFFFFFF");
  136.     StuffHex(whitePat, "\p0000000000000000");
  137.  
  138. #define WNETrapNum 0x60
  139. #define UnImplTrapNum 0x9F
  140.  
  141.     wne = NGetTrapAddress(WNETrapNum, ToolTrap) ==
  142.                     NGetTrapAddress(UnImplTrapNum, ToolTrap);
  143. }
  144.  
  145. void SetupMenus(void)
  146. {
  147.     MenuHandle MenuTopic ;
  148.     int index;
  149.  
  150.     MenuTopic=GetMenu(AppleMenu);
  151.     AddResMenu(MenuTopic,'DRVR');
  152.     InsertMenu(MenuTopic,0);
  153.  
  154.     for (index=FileMenu; index<=OptionsMenu; index++)
  155.             InsertMenu(GetMenu(index),0);
  156.  
  157.     InsertMenu(GetMenu(BlackMenu),-1);
  158.     InsertMenu(GetMenu(WhiteMenu),-1);
  159.  
  160.     DrawMenuBar();
  161. }
  162.  
  163.  
  164. void
  165. ShowPMessage (char *s)
  166. {
  167.   BlockMove(s, Msg, (long)*s + 1);
  168.   UpdateMsg(NULL, 3);
  169. }
  170.  
  171. void
  172. ShowCMessage (char *s)
  173. {
  174.   *Msg = strlen(s);
  175.   strcpy(Msg+1, s);
  176.   UpdateMsg(NULL, 3);
  177. }
  178.  
  179.  
  180. int RemoveMove(int GameCnt)
  181. {
  182.   Cell theCell;
  183.  
  184.   theCell.v = GameCnt/2;
  185.  
  186.   if (!(GameCnt&1)) {
  187.       LDelRow(1, theCell.v, List);
  188.   } else {
  189.       theCell.h = 1;
  190.       LClrCell(theCell, List);
  191.   }
  192.   
  193.   LScroll(0, 10000, List);
  194. }
  195.  
  196. int ShowError(int errno)
  197. {
  198.     ParamText(*GetString(errno), "", "", "");
  199.     return CautionAlert(_ERROR_ALRT, NULL);
  200. }
  201.  
  202. int AreYouSure(num)
  203. {
  204.     ParamText(*GetString(num), "", "", "");
  205.     return CautionAlert(_CONFIRM_ALRT, NULL) == 2;
  206. }
  207.  
  208. char choosePromo()
  209. {
  210.     int item;
  211.     DialogPtr theDlog;
  212.     
  213.     theDlog = GetNewDialog(_PROMO_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  214.     
  215.     SetPort(theDlog);
  216.     
  217.     ModalDialog(NULL, &item);
  218.     
  219.     DisposDialog(theDlog);
  220.     
  221.     switch (item) {
  222.         case 1: return 'Q';
  223.         case 2: return 'N';
  224.         case 3: return 'R';
  225.         case 4: return 'B';
  226.     }
  227. }
  228.  
  229. int chooseTime(int *moves, int *minutes)
  230. {
  231.     int item;
  232.     DialogPtr theDlog;
  233.     Str255 str;
  234.     long res;
  235.     Handle hdl;
  236.     Rect theRect;
  237.     int type;
  238.     
  239.     theDlog = GetNewDialog(_TIME_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  240.     
  241.     GetDItem(theDlog, 6, &type, &hdl, &theRect);
  242.     NumToString(*moves, str);
  243.     SetIText(hdl, str);
  244.     GetDItem(theDlog, 5, &type, &hdl, &theRect);
  245.     NumToString(*minutes, str);
  246.     SetIText(hdl, str);
  247.     
  248.     SetPort(theDlog);
  249.     
  250.     
  251.     do {
  252.         ModalDialog(NULL, &item);
  253.     } while ((item != 1) && (item != 2));
  254.     
  255.     if (item == 1) {
  256.         GetDItem(theDlog, 6, &type, &hdl, &theRect);
  257.         GetIText(hdl, str);
  258.         StringToNum(str, &res);
  259.         *moves = res;
  260.         GetDItem(theDlog, 5, &type, &hdl, &theRect);
  261.         GetIText(hdl, str);
  262.         StringToNum(str, &res);
  263.         *minutes = res;
  264.     }
  265.     
  266.     DisposDialog(theDlog);
  267.     
  268.     return (item==1);
  269. }
  270.  
  271. int AddMove(int GameCnt, char *mvstr)
  272. {
  273.   Cell theCell;
  274.   char mv[10];
  275.  
  276.   theCell.v = GameCnt/2;
  277.  
  278.   if (!(GameCnt&1)) {
  279.     int num = theCell.v + 1;
  280.     
  281.       theCell.h = 0;
  282.       LAddRow(1, theCell.v, List);
  283.       mv[0] = (num / 100)?(num/100 + '0'):' ';
  284.       mv[1] = ((num % 100) / 10)?((num % 100)/10 + '0'):' ';
  285.       mv[2] = num%10 + '0';
  286.       mv[3] = '.';
  287.       strcpy(mv + 4, mvstr);
  288.   } else {
  289.       theCell.h = 1;
  290.       strcpy(mv, mvstr);
  291.   }
  292.   
  293.   LSetCell((Ptr)mv, strlen(mv), theCell, List);
  294.   LDraw(theCell, List);
  295.   LScroll(0, 10000, List);
  296. }
  297.  
  298.  
  299. void
  300. Initialize ()
  301. {
  302.  int    i,j;
  303.  Rect    r;
  304.  Handle Hitem;
  305.  Cell Csize;
  306.  Rect bound;
  307.  
  308.     SetRect(&DragArea,
  309.             screenBits.bounds.left+4,
  310.             screenBits.bounds.top+24,
  311.             screenBits.bounds.right-4,
  312.             screenBits.bounds.bottom-4);
  313.     SetRect(&GrowArea,
  314.             80,
  315.             screenBits.bounds.top+60,
  316.             screenBits.bounds.right,
  317.             screenBits.bounds.bottom);
  318.     
  319.     WindBoard = GetNewDialog(770,(DialogPeek)0L,(WindowPtr)-1L);    
  320.     SetPort(WindBoard);
  321.     TextFont(geneva);
  322.     TextSize(9);
  323.     GetDItem(WindBoard, 1, &i, &Hitem, &chessRectOff);
  324.     SetDItem(WindBoard, 1, i, (Handle)UpdateGraphic, &chessRectOff);
  325.     width = 1+(chessRectOff.right-chessRectOff.left)/8;
  326.     height = width;
  327.  
  328.     GetDItem(WindBoard, 2, &i, &Hitem, &CaseFRec);
  329.     SetDItem(WindBoard, 2, i, (Handle)UpdateCase, &CaseFRec);
  330.     CaseRec = CaseFRec;
  331.     InsetRect(&CaseRec, 1, 1);
  332.         
  333.     
  334.     WindThink = GetNewDialog(_THINK_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  335.     SetPort(WindThink);
  336.     TextFont(monaco);
  337.     TextSize(9);
  338.     
  339.     GetDItem(WindThink, 1, &i, &Hitem, &nameRec);
  340.     SetDItem(WindThink, 1, i,  (Handle)UpdateChronos, &nameRec);
  341.     
  342.     GetDItem(WindThink, 5, &i, &Hitem, &ValueFRec);
  343.     SetDItem(WindThink, 5, i, (Handle)UpdateValue, &ValueFRec);
  344.     ValueRec = ValueFRec;
  345.     InsetRect(&ValueRec, 1, 1);
  346.     
  347.     GetDItem(WindThink, 4, &i, &Hitem, &MsgFRec);
  348.     SetDItem(WindThink, 4, i, (Handle)UpdateMsg, &MsgFRec);
  349.     MsgRec = MsgFRec;
  350.     InsetRect(&MsgRec, 1, 1);
  351.             
  352.     GetDItem(WindThink, 2, &i, &Hitem, &ThinkFRec[0]);
  353.     SetDItem(WindThink, 2, i, (Handle)UpdateThink, &ThinkFRec[0]);
  354.     ThinkRec[0] = ThinkFRec[0];
  355.     InsetRect(&ThinkRec[0], 1, 1);
  356.             
  357.     GetDItem(WindThink, 3, &i, &Hitem, &ThinkFRec[1]);
  358.     SetDItem(WindThink, 3, i, (Handle)UpdateThink, &ThinkFRec[1]);
  359.     ThinkRec[1] = ThinkFRec[1];
  360.     InsetRect(&ThinkRec[1], 1, 1);
  361.     
  362.     maxThink = (ThinkRec[1].bottom - ThinkRec[1].top - 5)/12 - 1;
  363.     
  364.     WindList = GetNewDialog(768, (DialogPeek)0L, (WindowPtr)-1L);
  365.     SetPort(WindList);
  366.     TextSize(9);
  367.     TextFont(monaco);
  368.     GetDItem(WindList, 1, &i, &Hitem, &r);
  369.     SetDItem(WindList, 1, i, (Handle)UpdateListe, &r);
  370.     r.right -= 15;
  371.     Csize.v=12;Csize.h=(r.right-r.left)/2;
  372.     bound.top = 0;
  373.     bound.left = 0;
  374.     bound.right = 2;
  375.     bound.bottom = 0;
  376.     List=LNew(&r,&bound,Csize,0,WindList,TRUE,FALSE,FALSE,TRUE);
  377.  
  378.     theBar = r;
  379.     theBar.left = r.right;
  380.     theBar.right += 15;
  381.     
  382.        (**List).selFlags=lOnlyOne;
  383.                     
  384.     LAutoScroll(List);
  385.  
  386.     ShowWindow(WindList);
  387.     
  388.     SetPort(WindBoard);
  389.     MouseX = MouseY = 0;
  390.         
  391.     UpdateChronos(NULL, 2);
  392.     UpdateValue(NULL, 5);
  393.     UpdateMsg(NULL, 3);
  394.     UpdateCase(NULL, 4);
  395.     
  396.     SetPort(WindBoard);
  397.     InitDrag(0L, &chessRectOff);
  398.     UpdateDisplay(0,0,1,0,1,color,board);
  399.     
  400.     InitCursor();
  401. }
  402.  
  403. void
  404. ExitChess ()
  405. {
  406.   CloseDrag(0);
  407. }
  408.  
  409.  
  410. void
  411. algbr (f, t, flag)
  412.      short int f;
  413.      short int t;
  414.      short int flag;
  415. /*
  416.    Generate move strings in different formats, a hook has been provided for
  417.    underpromotion
  418. */
  419.  
  420. {
  421.   int m3p;
  422.  
  423.   if (f != t)
  424.     {
  425.       /* algebraic notation */
  426.       mvstr[0][0] = cxx[column (f)];
  427.       mvstr[0][1] = rxx[row (f)];
  428.       mvstr[0][2] = cxx[column (t)];
  429.       mvstr[0][3] = rxx[row (t)];
  430.       mvstr[0][4] = '\0';
  431.       mvstr[3][0] = '\0';
  432.       if ((mvstr[1][0] = qxx[board[f]]) == 'P')
  433.     {
  434.       if (mvstr[0][0] == mvstr[0][2])    /* pawn did not eat */
  435.         {
  436.           mvstr[2][0] = mvstr[1][0] = mvstr[0][2];    /* to column */
  437.           mvstr[2][1] = mvstr[1][1] = mvstr[0][3];    /* to row */
  438.           m3p = 2;
  439.         }
  440.       else
  441.         /* pawn ate */
  442.         {
  443.           mvstr[2][0] = mvstr[1][0] = mvstr[0][0];    /* from column */
  444.           mvstr[2][1] = mvstr[1][1] = mvstr[0][2];    /* to column */
  445.           mvstr[2][2] = mvstr[0][3];
  446.           m3p = 3;        /* to row */
  447.         }
  448.       mvstr[2][m3p] = mvstr[1][2] = '\0';
  449.       if (flag & promote)
  450.         {
  451.           mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  452.           mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  453.         }
  454.     }
  455.       else
  456.     /* not a pawn */
  457.     {
  458.       mvstr[2][0] = mvstr[1][0];
  459.       mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  460.       mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  461.       mvstr[2][4] = mvstr[1][3] = '\0';
  462.       mvstr[2][1] = mvstr[0][1];
  463.       strcpy (mvstr[3], mvstr[2]);
  464.       mvstr[3][1] = mvstr[0][0];
  465.       if (flag & cstlmask)
  466.         {
  467.           if (t > f)
  468.         {
  469.           strcpy (mvstr[1], "o-o");
  470.           strcpy (mvstr[2], "O-O");
  471.         }
  472.           else
  473.         {
  474.           strcpy (mvstr[1], "o-o-o");
  475.           strcpy (mvstr[2], "O-O-O");
  476.         }
  477.         }
  478.     }
  479.     }
  480.   else
  481.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  482. }
  483.  
  484. void
  485. seteasy()
  486. {
  487.   easy = !easy;
  488. }
  489.  
  490.  
  491. int
  492. VerifyMove (s, iop, mv)
  493.      char *s;
  494.      short int iop;
  495.      short unsigned int *mv;
  496. /*
  497.    Compare the string 's' to the list of legal moves available for the
  498.    opponent. If a match is found, make the move on the board.
  499. */
  500. {
  501.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  502.   static struct leaf xnode;
  503.   struct leaf *node;
  504.  
  505.   *mv = 0;
  506.   if (iop == 2)
  507.     {
  508.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  509.       return (false);
  510.     }
  511.   cnt = 0;
  512.   MoveList (opponent, 2);
  513.   pnt = TrPnt[2];
  514.   while (pnt < TrPnt[3])
  515.     {
  516.       node = &Tree[pnt++];
  517.       algbr (node->f, node->t, (short) node->flags);
  518.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  519.           strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  520.         {
  521.           cnt++;
  522.           xnode = *node;
  523.         }
  524.     }
  525.   if (cnt == 1)
  526.     {
  527.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, 0);
  528.       if (SqAtakd (PieceList[opponent][0], computer))
  529.         {
  530.           UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  531.           return (false);
  532.         }
  533.       else
  534.         {
  535.           if (iop == 1)
  536.             return (true);
  537.           if (xnode.flags & cstlmask)
  538.             Game50 = GameCnt;
  539.           else if (board[xnode.t] == pawn || (xnode.flags & capture))
  540.             Game50 = GameCnt;
  541.           GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  542.           GameList[GameCnt].nodes = 0;
  543.           GameList[GameCnt].time = (short) et;
  544.           GameList[GameCnt].flags = xnode.flags;
  545.           TimeControl.clock[opponent] -= et;
  546.           --TimeControl.moves[opponent];
  547.           
  548.           ElapsedTime(1);
  549.  
  550.           *mv = (xnode.f << 8) + xnode.t;
  551.           algbr (xnode.f, xnode.t, xnode.flags);
  552.  
  553.           if (xnode.flags & epmask)
  554.             UpdateDisplay (0, 0, 1, 0, 1, color, board);
  555.           else
  556.             UpdateDisplay(xnode.f, xnode.t, 0, (short) xnode.flags & cstlmask, 0,
  557.                            color, board);
  558.           return (true);
  559.         }
  560.     }
  561.   return (false);
  562. }
  563.  
  564. void
  565. ShowResults (score, bstline, ch)
  566.      short int score;
  567.      short unsigned int *bstline;
  568.      char ch;
  569. {
  570.   short d, e, ply;
  571.   theScore = score;
  572.   if (showvalue) UpdateValue(0L,5);
  573.   if (post)
  574.     {
  575.       GrafPtr SavePort;
  576.       int h,v;
  577.       
  578.        GetPort(&SavePort);
  579.       SetPort(WindThink);
  580.       TextMode(srcCopy);
  581.  
  582.       d = 0;
  583.       
  584.       h = ThinkRec[computer].left+2;
  585.       v = ThinkRec[computer].top+15;
  586.       
  587.       for (ply = 1; bstline[ply] > 0; ply++)
  588.     {
  589.       algbr (bstline[ply] >> 8, bstline[ply] & 0xFF, false);
  590.       strcpy(ThinkMove[computer][d]+1, mvstr[0]);
  591.       ThinkMove[computer][d][0] = strlen(mvstr[0]);
  592.       MoveTo(h,v);
  593.       DrawString(ThinkMove[computer][d]);
  594.       if (++d>maxThink) break;
  595.       v += 12;
  596.     }
  597.       lpost = d;
  598.       while (d <= maxThink)
  599.     {
  600.       MoveTo(h,v);
  601.       ThinkMove[computer][d++][0] = 0;
  602.       v += 12;
  603.       DrawString("\p       ");
  604.     }
  605.     SetPort(SavePort);
  606.     }
  607. }
  608.  
  609.  
  610. void
  611. SearchStartStuff (side)
  612.      short int side;
  613. {
  614.   short i;
  615.   
  616.   SetPort(WindThink);
  617.   ThinkMove[side][0][0] = 0;
  618.   EraseRect(&ThinkRec[side]);
  619. }
  620.  
  621. void
  622. OutputMove ()
  623. {
  624.   int i;
  625.  
  626.   ShowCMessage(""); 
  627.   if (SqAtakd (PieceList[!towho][0], towho))
  628.   {
  629.     ShowPMessage(*(char **)GetString(_CHECK_STR));
  630.     SysBeep(1);
  631.   }
  632.   
  633.   AddMove(GameCnt, mvstr[(root->flags & cstlmask) != 0]);
  634.   
  635.   for (i=0; i<64; i++) {
  636.       saveBoard[i] = board[i];
  637.       saveColor[i] = color[i];
  638.   }
  639.   
  640.   if (root->flags & epmask)
  641.     UpdateDisplay (0, 0, 1, 0, 1, color, board);
  642.   else
  643.     UpdateDisplay (root->f, root->t, 0, root->flags & cstlmask, 1, color, board);
  644.  
  645.   if (root->flags & draw) {
  646.     ShowPMessage(*(char **)GetString(_DRAWN_STR));
  647.     drawn = true;
  648.     SysBeep(1);
  649.   }
  650.   else if (root->score == -9999) {
  651.     ShowPMessage(*(char **)GetString(_MATE_STR));
  652.     SysBeep(1);
  653.   }
  654.   else if (root->score == 9998) {
  655.     ShowPMessage(*(char **)GetString(_MATE_STR));
  656.     SysBeep(1);
  657.   }
  658.   else if (root->score < -9000) {
  659.     ShowPMessage(*(char **)GetString(_SOON_STR));
  660.     SysBeep(1);
  661.   }
  662.   else if (root->score > 9000) {
  663.     ShowPMessage(*(char **)GetString(_SOON_STR));
  664.     SysBeep(1);
  665.   }
  666. }
  667.  
  668. void
  669. ElapsedTime(iop)
  670.      short int iop;
  671. /*
  672.   Determine the time that has passed since the search was started. If
  673.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  674.   timeout to true which will terminate the search.
  675. */
  676. {
  677.   static unsigned long LastClick = 0;
  678.   
  679.   et = (Ticks - time0)/60;
  680.   if (et < 0) {
  681.       et = 0;
  682.   }
  683.   if (((Ticks-LastClick)>10) && (towho == computer || bothsides || preview)) {
  684.       if (mainLoop()) timeout = true;
  685.       LastClick = Ticks;
  686.   }
  687.  
  688.   ETnodes += 50;
  689.   if (et > et0 || iop == 1)
  690.     {
  691.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  692.             timeout = true;
  693.       et0 = et;
  694.       if (iop == 1)
  695.       {
  696.             time0 = Ticks;
  697.             et0 = 0;
  698.       }
  699.       if (et > 0)
  700.             /* evrate is Nodes / cputime */
  701.             evrate = NodeCnt / (et + ft);
  702.       else    evrate = 0;
  703.       
  704.       ETnodes = NodeCnt + 50;
  705.       UpdateClocks ();
  706.     }
  707.     
  708. }
  709.  
  710. void
  711. UpdateClocks ()
  712. {    
  713.     static unsigned long LastDraw = 0;
  714.     static int LastColor = black;
  715.     
  716.     if (LastColor!=towho || Ticks-LastDraw>45) {
  717.             UpdateChronos(NULL, 0);
  718.             LastDraw = Ticks; LastColor = towho;
  719.     }
  720. }
  721.  
  722.  
  723. void
  724. SetTimeControl (color)
  725. {
  726.   if (TCflag[color])
  727.     {
  728.       TimeControl.moves[color] = TCmoves[color];
  729.       TimeControl.clock[color] = 60 * (long) TCminutes[color];
  730.     }
  731.   else
  732.     {
  733.       TimeControl.moves[color] = 0;
  734.       TimeControl.clock[color] = 0;
  735.       Level[color] = 60 * (long) TCminutes[color];
  736.     }
  737.   et = 0;
  738.   ElapsedTime (1);
  739. }
  740.  
  741.  
  742. void
  743. Undo ()
  744. /*
  745.   Undo the most recent half-move.
  746.   */
  747. {
  748.   short f, t, i;
  749.   
  750.   RemoveMove(GameCnt);
  751.   f = GameList[GameCnt].gmove >> 8;
  752.   t = GameList[GameCnt].gmove & 0xFF;
  753.   if (board[t] == king && distance (t, f) > 1)
  754.     {
  755.         castle (GameList[GameCnt].color, f, t, 2);
  756.           DrawPieces (PieceToNum(color[t], board[t]), t);
  757.           DrawPieces (PieceToNum(color[f], board[f]), f);    
  758.           if (distance(t,f) == 2) {
  759.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  760.               DrawPieces (PieceToNum(color[t-1], board[t-1]), t-1);
  761.           } else {
  762.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  763.               DrawPieces (PieceToNum(color[t-2], board[t-2]), t-2);
  764.           }    
  765.     }
  766.   else
  767.     {
  768.       board[f] = board[t];
  769.       color[f] = color[t];
  770.       board[t] = GameList[GameCnt].piece;
  771.       color[t] = GameList[GameCnt].color;
  772.       DrawPieces(PieceToNum(color[t], board[t]), t);
  773.       DrawPieces(PieceToNum(color[f], board[f]), f);
  774.     }
  775.   if (TCflag[color[f]])
  776.     ++TimeControl.moves[color[f]];
  777.   GameCnt--;
  778.   drawn = mate = false;
  779.   Sdepth = 0;
  780.   Mvboard[f]--;
  781.   for (i=0; i<64; i++) {
  782.       saveColor[i] = color[i];
  783.       saveBoard[i] = board[i];
  784.   }
  785.   InitializeStats ();
  786. }
  787.  
  788. void
  789. ShowCurrentMove (pnt, f, t)
  790.      short int pnt;
  791.      short int f;
  792.      short int t;
  793. {
  794. }
  795.  
  796.  
  797. void
  798. GiveHint ()
  799. {
  800.   char s[40];
  801.   int f, t;
  802.   
  803.   if (!hint) return;
  804.   
  805.   f = hint >> 8;
  806.   t = hint & 0xFF;
  807.   
  808.   algbr ((short) f, (short) t, false);
  809.   ShowCMessage (mvstr[0]);
  810.   AnimePieces(0,PieceToNum(saveColor[f], saveBoard[f]),f, t, 1);
  811.   AnimePieces(PieceToNum(saveColor[t], saveBoard[t]),
  812.                 PieceToNum(saveColor[f], saveBoard[f]),
  813.                     t, f, 1);
  814. }
  815.  
  816.  
  817. void
  818. InputCommand ()
  819. /*
  820.   Process the users command. If easy mode is OFF (the computer is
  821.   thinking on opponents time) and the program is out of book, then make
  822.   the 'hint' move on the board and call SelectMove() to find a response.
  823.   The user terminates the search by entering ^C (quit siqnal) before
  824.   entering a command. If the opponent does not make the hint move, then
  825.   set Sdepth to zero.
  826.   */
  827. {
  828.   short ok, i, tmp;
  829.   long cnt, rate, t1, t2;
  830.   unsigned short mv;
  831.   char s[80];
  832.  
  833.   ok = quit = false;
  834.  
  835.   player = opponent = towho;
  836.   computer = !towho;
  837.   
  838.   ft = 0;
  839.   if (hint > 0 && !easy && Book == NULL)
  840.     {
  841.       preview = 1; idoit = 0;
  842.       time0 = Ticks;
  843.       algbr (hint >> 8, hint & 0xFF, false);
  844.       strcpy (s, mvstr[0]);
  845.       tmp = epsquare;
  846.       if (VerifyMove (s, 1, &mv))
  847.       {
  848.             SelectMove (computer, 2);
  849.             VerifyMove (mvstr[0], 2, &mv);
  850.             if (Sdepth > 0)
  851.                 Sdepth--;
  852.       }
  853.       ft = (Ticks - time0)/60;
  854.       epsquare = tmp;
  855.       preview = 0;
  856.     }
  857.  
  858.   ok = idoit;
  859.   while (!(ok || quit))
  860.   {
  861.         ElapsedTime(0);
  862.       ok = mainLoop();
  863.   }
  864.   ElapsedTime(1);
  865.   ShowCMessage("");
  866. }
  867.  
  868. static void mouseToXY(Point pt, int *OuX, int *OuY)
  869. {
  870.     *OuX = (pt.h/(width-1))+1;
  871.     *OuX = scrntoxy(*OuX);
  872.     *OuY= 8 - (pt.v/(height-1));
  873.     *OuY = scrntoxy(*OuY);
  874. }
  875.  
  876.  
  877. static void followMouse(int *x1, int *y1, Point *Dum)
  878. {
  879.     do {
  880.         GetMouse(Dum);
  881.         PicInRect(&chessRectOff, myDragStuff, Dum);
  882.         mouseToXY(*Dum,x1,y1);
  883.         if ((MouseX!= *x1) || (MouseY != *y1))
  884.         {
  885.             MouseX = *x1; MouseY = *y1;
  886.             UpdateCase(0L,4);
  887.         }
  888.         else
  889.         {
  890.             MouseX = *x1; MouseY = *y1;
  891.         }
  892.         DragItTo(myDragStuff,*Dum,1, FALSE);
  893.          ElapsedTime (0);
  894.     } while (StillDown());
  895. }
  896.  
  897. static void playTheMove(int sq, int x1, int y1, Point Dum)
  898. {
  899.     Point theEnd;
  900.     Rect r;
  901.     
  902.     theEnd = CenterRect(Rectangle(scrntoxy(x1),scrntoxy(9-y1), &r));
  903.     DrawPieces(no_piece, sq);
  904.     DragFromTo(myDragStuff, Dum, theEnd);
  905.     DisposeDraggable(myDragStuff);
  906. }
  907.  
  908.  
  909.  
  910. int MouseInContent(Point MouseLoc, int *eatit)            
  911. {
  912.     int x,y,x1,y1,i,j,ok;
  913.     
  914.     ok = 0;
  915.     if (FrontWindow()==WindList) {
  916.         SetPort(WindList);
  917.         GlobalToLocal(&MouseLoc);
  918.         if (PtInRect(MouseLoc, &theBar)) LClick(MouseLoc, 0, List);
  919.         LocalToGlobal(&MouseLoc);
  920.     } else
  921.     if ((FrontWindow()==WindBoard) && (((opponent == towho) && (!bothsides))
  922.                                     || force) )
  923.     {
  924.         SetPort(WindBoard);
  925.         GlobalToLocal(&MouseLoc);
  926.         mouseToXY(MouseLoc,&x,&y);
  927.         if (y>=1 && y<=8)
  928.          {
  929.              Rect r;
  930.              int Num;
  931.              
  932.              int sq = (y-1)*8+x-1;
  933.              int sq1;
  934.              
  935.              MouseX=x;MouseY=y; UpdateCase(0L,4);
  936.             SetRect(&r,0,0,8*(width-1),8*(height-1));
  937.             if ((saveBoard[sq]!=no_piece)&&(saveColor[sq]==towho))
  938.             {
  939.                 Point Dum;
  940.                 PicHandle h1, h2;
  941.                 char s[6];
  942.                 unsigned int mv;
  943.                 
  944.                 if (preview) {
  945.                     *eatit = false;
  946.                     return 1;
  947.                 }
  948.  
  949.                  Num=PieceToNum(saveColor[sq],saveBoard[sq]);
  950.                 DrawPieces(no_piece ,sq);
  951.                 
  952.                 Dum=MouseLoc;
  953.                 h1=GetPicture(Num);
  954.                 HNoPurge((Handle)(h1));
  955.                 h2=GetPicture(Num-1+Num%4);
  956.                 HNoPurge((Handle)(h1));
  957.         
  958.                 NewDraggable(h1,h2,0L,0L, &myDragStuff);
  959.         
  960.                 HPurge((Handle)(h1));
  961.                 HPurge((Handle)(h2));
  962.         
  963.                  ShadowStuff.visible = 1;
  964.                  ShadowStuff.dx = 4;
  965.                  ShadowStuff.dy = 4;
  966.         
  967.                 followMouse(&x1, &y1, &Dum);
  968.  
  969.                 sq1 = (y1-1)*8+x1-1;
  970.                 if ((saveBoard[sq]==king) && (x1-x == 2)) strcpy(s,"o-o");
  971.                 else 
  972.                 if ((saveBoard[sq]==king) && (x-x1 == 3)) strcpy(s,"o-o-o");
  973.                 else {
  974.                     s[0] = x+'a'-1;
  975.                     s[1] = y+'0';
  976.                     s[2] = x1+'a'-1;
  977.                     s[3] = y1+'0';
  978.                     if (saveBoard[sq] == pawn && (y1 == 8 || y1 == 1)) {
  979.                             s[4] = choosePromo();
  980.                             s[5] = 0;
  981.                     } else  s[4] = 0;
  982.                 }
  983.                 
  984.                 if (ok = VerifyMove(s, 1, &mv)) {
  985.                       if (mv != hint)
  986.                     {
  987.                       Sdepth = 0;
  988.                       ft = 0;
  989.                     }
  990.                     VerifyMove (s, 2, &mv);
  991.                     playTheMove(sq, x1, y1, Dum);
  992.                     VerifyMove (s, 0, &mv);
  993.                     DrawPieces(PieceToNum(color[sq1], board[sq1]), sq1);
  994.                     AddMove(GameCnt, s);
  995.                 } else /* Not valid... Go back home */
  996.                     {
  997.                         Rect r;
  998.                         Point theEnd;
  999.                         theEnd = CenterRect(Rectangle(scrntoxy(x),scrntoxy(9-y), &r));
  1000.                         DragFromTo(myDragStuff,Dum,theEnd);
  1001.                         DisposeDraggable(myDragStuff);
  1002.                     }
  1003.         } else while (StillDown());
  1004.         LocalToGlobal(&MouseLoc);
  1005.     }
  1006. }
  1007.     return ok;
  1008. }
  1009.  
  1010. int ProcessMenu_in(long CodeWord)
  1011. {
  1012.     MenuHandle MenuTopic;
  1013.     int Menu_No;
  1014.     int Item_No;
  1015.     Str255 NameHolder;
  1016.     int wind,i,Err;
  1017.     Rect nulrec;
  1018.     Handle ItemHdl;
  1019.     
  1020.     int ok = 0;
  1021.     if (CodeWord)
  1022.         {
  1023.         int change = false;
  1024.         Menu_No=HiWord(CodeWord);
  1025.         Item_No=LoWord(CodeWord);
  1026.  
  1027.         switch (Menu_No) {
  1028.  
  1029.             case AppleMenu:
  1030.                 if (Item_No==1) {
  1031.                     Alert(_ABOUT_ALRT, NULL);
  1032.                 }
  1033.                 else {
  1034.                     GetItem(GetMHandle(AppleMenu),Item_No,NameHolder);
  1035.                     OpenDeskAcc(NameHolder);
  1036.                 }
  1037.                 break;
  1038.             case FileMenu:
  1039.                 switch (Item_No) {
  1040.                 case 1:
  1041.                     if (!AreYouSure(_END_STR)) break;
  1042.                     newgame = 1;
  1043.                     donotplay = 1;
  1044.                     ok = true;
  1045.                     break;
  1046.                 case 2:
  1047.                     if (!AreYouSure(_END_STR)) break;
  1048.                     getgame = 1;
  1049.                     donotplay = 1;
  1050.                     ok = true;
  1051.                     break;
  1052.                 case 3:
  1053.                     SaveGame();
  1054.                     break;
  1055.                 case 5:
  1056.                     ListGame();
  1057.                     break;
  1058.                 case 7:
  1059.                     if (!AreYouSure(_END_STR)) break;
  1060.                     donotplay = 1;
  1061.                     quit = true;
  1062.                     ok = true;
  1063.                     break;
  1064.                 }
  1065.                 break;
  1066.  
  1067.             case EditMenu:
  1068.                 if (!SystemEdit(Item_No-1))
  1069.                     switch (Item_No) {
  1070.                         case 1:
  1071.                             if (GameCnt >= 0) {
  1072.                                 undo = 1;
  1073.                                 donotplay = 1;
  1074.                                 Sdepth = 0;
  1075.                                 ok = 1;
  1076.                             }
  1077.                             break;
  1078.                 }
  1079.                 break;
  1080.             case PlayerMenu:
  1081.                 switch (Item_No) {
  1082.                     case 1:
  1083.                         donotplay = true;
  1084.                         bothsides = false;
  1085.                         computer = black;
  1086.                         opponent = white;
  1087.                         ok = true;
  1088.                         force = false;
  1089.                         Sdepth = 0;
  1090.                         break;
  1091.                     case 2:
  1092.                         donotplay = true;
  1093.                         bothsides = false;
  1094.                         computer = white;
  1095.                         opponent = black;
  1096.                         ok = true;
  1097.                         force = false;
  1098.                         Sdepth = 0;
  1099.                         break;
  1100.                     case 3:
  1101.                         donotplay = true;
  1102.                         bothsides = true;
  1103.                         computer = towho;
  1104.                         opponent = !towho;
  1105.                         Sdepth = 0;
  1106.                         ok = true;
  1107.                         force = false;
  1108.                         break;
  1109.                     case 4:
  1110.                         force = true;
  1111.                         bothsides = false;
  1112.                         donotplay = true;
  1113.                         computer = !towho;
  1114.                         opponent = towho;
  1115.                         Sdepth = 0;
  1116.                         ok = true;
  1117.                         break;
  1118.                 }
  1119.                 if (Item_No>0 && Item_No<5)
  1120.                       for (i=1; i<=4; i++)
  1121.                           CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1122.                 break;
  1123.             case WhiteMenu:
  1124.             case BlackMenu:
  1125.               switch (Item_No)
  1126.                 {
  1127.                   
  1128.                 case 1:
  1129.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1130.                   TCminutes[Menu_No==WhiteMenu?white:black] = 5;
  1131.                   change = true;
  1132.                   break;
  1133.                 case 2:
  1134.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1135.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1136.                   change = true;
  1137.                   break;
  1138.                 case 3:
  1139.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1140.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1141.                   change = true;
  1142.                   break;
  1143.                 case 4:
  1144.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1145.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1146.                   change = true;
  1147.                   break;
  1148.                 case 5:
  1149.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1150.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1151.                   change = true;
  1152.                   break;
  1153.                 case 6:
  1154.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1155.                   TCminutes[Menu_No==WhiteMenu?white:black] = 120;
  1156.                   change = true;
  1157.                   break;
  1158.                 case 7:
  1159.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1160.                   TCminutes[Menu_No==WhiteMenu?white:black] = 240;
  1161.                   change = true;
  1162.                   break;
  1163.                 case 8:
  1164.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1165.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1166.                   change = true;
  1167.                   break;
  1168.                 case 9:
  1169.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1170.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1171.                   change = true;
  1172.                   break;
  1173.                 case 10:
  1174.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1175.                   TCminutes[Menu_No==WhiteMenu?white:black] = 600;
  1176.                   change = true;
  1177.                   break;
  1178.                 case 12:
  1179.                   change = chooseTime(&TCmoves[Menu_No==WhiteMenu?white:black]
  1180.                                   ,&TCminutes[Menu_No==WhiteMenu?white:black]);
  1181.                   break;
  1182.                 }
  1183.             
  1184.               if (change) {
  1185.                   for (i=1; i<=12; i++)
  1186.                       CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1187.                   SetTimeControl (Menu_No==WhiteMenu?white:black);
  1188.               }
  1189.               break;
  1190.             case OptionsMenu:
  1191.                 switch (Item_No) {
  1192.                     case 1:
  1193.                         easy = !easy;
  1194.                         CheckItem(GetMHandle(Menu_No), Item_No, easy);
  1195.                         break;
  1196.                     case 2:
  1197.                         reverse = !reverse;
  1198.                         UpdateDisplay(0, 0, 1, 0, 1, saveColor, saveBoard);
  1199.                         CheckItem(GetMHandle(Menu_No), Item_No, reverse);
  1200.                         break;
  1201.                     case 3:
  1202.                         anim = !anim;
  1203.                         CheckItem(GetMHandle(Menu_No), Item_No, anim);
  1204.                         break;
  1205.                     case 4:
  1206.                         dither = dither?0:6;
  1207.                         CheckItem(GetMHandle(Menu_No), Item_No, dither!=0);
  1208.                         break;
  1209.                     case 5:
  1210.                         post = !post;
  1211.                         CheckItem(GetMHandle(Menu_No), Item_No, post);
  1212.                         break;
  1213.                     case 6:
  1214.                         showvalue = !showvalue;
  1215.                         CheckItem(GetMHandle(Menu_No), Item_No, showvalue);
  1216.                         break;
  1217. #ifdef HASHFILE
  1218.                     case 7:
  1219.                         hashflag = !hashflag;
  1220.                         if (hashflag) hashflag = CheckHashFile();
  1221.                         CheckItem(GetMHandle(Menu_No), Item_No, hashflag);
  1222.                         break;
  1223. #endif
  1224.                     case 8:
  1225.                         break;
  1226.                     case 9:
  1227.                         GiveHint();
  1228.                         break;
  1229.                     case 10:
  1230.                         timeout = true;
  1231.                         ok = true;
  1232.                         break;
  1233.                 }
  1234.         }
  1235.  
  1236.         HiliteMenu(0);
  1237.     }
  1238.     return ok;
  1239. }
  1240.  
  1241. int DealwthMouseDowns(EventRecord *Event, int *eatit)
  1242. {
  1243.     int Location;
  1244.     WindowPtr WindowPointedTo;
  1245.     Point MouseLoc,theEnd;
  1246.     int WindoLoc;
  1247.     long Hw,NS;
  1248.     Rect r,rDum;
  1249.     int x,y,x1,y1,i,j;
  1250.     RgnHandle rg;
  1251.     Point Dum;
  1252.     Str255 C;
  1253.     Boolean Bool;
  1254.     int Item,ItemType,Num;
  1255.     Handle ItemHdl;
  1256.     PicHandle h1,h2;
  1257.  
  1258.     *eatit = true;
  1259.     MouseLoc = Event->where;
  1260.     WindoLoc = FindWindow(MouseLoc,&WindowPointedTo);
  1261.     switch (WindoLoc) {
  1262.         case inMenuBar:
  1263.             return ProcessMenu_in((long)MenuSelect(MouseLoc));
  1264.             break;
  1265.         case inSysWindow:
  1266.             SystemClick(Event,WindowPointedTo);
  1267.             break;
  1268.         case inContent:
  1269.             if (WindowPointedTo != FrontWindow()) 
  1270.                 SelectWindow(WindowPointedTo);
  1271.             else return MouseInContent(MouseLoc, eatit);
  1272.             break;
  1273.         case inGrow:
  1274.             if (WindowPointedTo != FrontWindow())
  1275.                 SelectWindow(WindowPointedTo);
  1276.             else
  1277.                 {
  1278.                 Hw = GrowWindow(WindowPointedTo, MouseLoc, &GrowArea);
  1279.                 SizeWindow(WindowPointedTo,Hw & 0xFFFF, Hw>>16, 1);
  1280.                 r = WindowPointedTo->portRect;
  1281.                 ClipRect(&r);
  1282.                 EraseRect(&r);
  1283.                 InvalRect(&r);
  1284.                 }
  1285.                 break;
  1286.         case inDrag:
  1287.                 DragWindow(WindowPointedTo,MouseLoc,&DragArea);
  1288.                 break;
  1289.  
  1290.         case inGoAway:
  1291.                 if (TrackGoAway(WindowPointedTo,MouseLoc))
  1292.                     HideWindow(WindowPointedTo);
  1293.                 break;
  1294.         case inZoomIn:
  1295.         case inZoomOut:
  1296.                 if  (WindowPointedTo != FrontWindow())
  1297.                     SelectWindow(WindowPointedTo);
  1298.                 else
  1299.                 {
  1300.                 ZoomWindow(WindowPointedTo,WindoLoc,1);
  1301.                 r =WindowPointedTo->portRect;
  1302.                 Hw = r.bottom - r.top;
  1303.                 NS = Hw>>16 + r.right - r.left;
  1304.                 if (NS)
  1305.                 {
  1306.                 SizeWindow(WindowPointedTo,NS & 0xFFFF,NS>>16,1);
  1307.                 r = WindowPointedTo->portRect;
  1308.                 ClipRect(&r);
  1309.                 EraseRect(&r);
  1310.                 InvalRect(&r);
  1311.                 }
  1312.                 }
  1313.                 break;
  1314.     }        
  1315.     return 0;
  1316. }
  1317.  
  1318.  
  1319. void DealWthNull(EventRecord *Event)
  1320. {
  1321.     WindowPtr WindowPointedTo;
  1322.     Point MouseLoc;
  1323.     int WindoLoc;
  1324.     int x,y;
  1325.     Boolean Update;
  1326.  
  1327.     WindoLoc=FindWindow(MouseLoc=Event->where,&WindowPointedTo);
  1328.     
  1329.     if ((WindoLoc==inContent) && (WindowPointedTo==WindBoard))
  1330.     {
  1331.         SetPort(WindBoard);
  1332.         GlobalToLocal(&MouseLoc);
  1333.         mouseToXY(MouseLoc,&x,&y);
  1334.         if (y>0 && y<9 && x>0 && x<9)
  1335.         {
  1336.             Update=(MouseX!=x) || (MouseY!=y);
  1337.             MouseX=x;
  1338.             MouseY=y;
  1339.             if (Update) {
  1340.                 UpdateCase(0L,4);
  1341.             }
  1342.         }
  1343.     }
  1344. }
  1345.  
  1346. int mainLoop()
  1347. {
  1348.     EventRecord evt;
  1349.     int ok, eatit, res, item;
  1350.     DialogPtr dlog;
  1351.     char theChar;
  1352.     
  1353.     res = 0;
  1354.     
  1355.     if (wne)
  1356.         ok = WaitNextEvent(everyEvent, &evt, 0L, NULL);
  1357.     else {
  1358.         SystemTask();
  1359.         ok = GetNextEvent(everyEvent, &evt);
  1360.     }
  1361.     if (!ok) {
  1362.         if (force || (towho == opponent)) DealWthNull(&evt);
  1363.         return 0;
  1364.     }
  1365.  
  1366.     eatit = preview;
  1367.     
  1368.     switch (evt.what) {
  1369.         case mouseDown:
  1370.             res = DealwthMouseDowns(&evt, &eatit);
  1371.             break;
  1372.         case keyDown:
  1373.         case autoKey: 
  1374.             theChar = evt.message & charCodeMask;
  1375.             if ((evt.modifiers & cmdKey) != 0) 
  1376.             res = ProcessMenu_in( MenuKey( theChar ));
  1377.             break;
  1378.         case activateEvt: 
  1379.             break;
  1380.         case updateEvt:
  1381.             break;
  1382.         case 15 : /* Multifinder Event */
  1383.             if ((evt.message & 0xFF000000) != 0xFA000000) {
  1384.                         background = !(evt.message & 1);
  1385.             }
  1386.             break;
  1387.         default:
  1388.             break;
  1389.     }
  1390.  
  1391.     if (IsDialogEvent(&evt)) {
  1392.         DialogSelect(&evt, &dlog, &item);
  1393.     }
  1394.  
  1395.     if (!eatit && preview) {
  1396.         static EvQEl globEvt;
  1397.         /* We re-post the event. */
  1398.         globEvt.qType = evType;
  1399.         globEvt.evtQWhat = evt.what;
  1400.         globEvt.evtQMessage = evt.message;
  1401.         globEvt.evtQWhen = evt.when;
  1402.         globEvt.evtQWhere.h = evt.where.h;
  1403.         globEvt.evtQWhere.v = evt.where.v;
  1404.         globEvt.evtQModifiers = evt.modifiers;
  1405.         Enqueue((QElemPtr)&globEvt, (QHdrPtr)GetEvQHdr());
  1406.     }
  1407.     return res;
  1408. }
  1409.  
  1410.  
  1411. loop()
  1412. {
  1413.   int i;
  1414.   
  1415.   SetCursor(*ClockCursor);
  1416.   towho = white;
  1417.   opponent = white;
  1418.   computer = black;
  1419.   bothsides = false;
  1420.   force = reverse = post = easy = false;
  1421.   hashflag = false;
  1422.   drawn = 0;
  1423.   NewGame();
  1424.   for (i=0; i<64; i++) {
  1425.       saveBoard[i] = board[i];
  1426.       saveColor[i] = color[i];
  1427.   }
  1428.   theScore = 0;
  1429.   UpdateValue(NULL, 0);
  1430.   *Msg = 0;
  1431.   UpdateMsg(NULL, 3);
  1432.   
  1433.   UpdateDisplay(0,0,1,0,1,color,board);
  1434.   undo = getgame = newgame = preview = 0;
  1435.   while (!(quit))
  1436.     {
  1437.       player = towho;
  1438.       if (force)
  1439.       {
  1440.           opponent = player;
  1441.           computer = otherside[player];
  1442.       }
  1443.       if (bothsides)
  1444.       {
  1445.           computer = player;
  1446.           opponent = otherside[player];
  1447.       }
  1448.      
  1449.       UpdateMenus();
  1450.       
  1451.       if (undo) {
  1452.               Undo();
  1453.               undo = 0;
  1454.               towho = !towho;
  1455.           }
  1456.           if (getgame) {
  1457.             SetCursor(*ClockCursor);
  1458.             Sdepth = 0;
  1459.             GetGame();
  1460.               getgame = 0;
  1461.           }
  1462.           if (newgame) {
  1463.             SetCursor(*ClockCursor);
  1464.               LDelRow(0, 0, List);
  1465.             NewGame();
  1466.             for (i=0; i<64; i++) {
  1467.                   saveColor[i] = color[i];
  1468.                   saveBoard[i] = board[i];
  1469.             }
  1470.             UpdateDisplay(0,0,1,0,1,color,board);
  1471.             towho = white;
  1472.             if (force) {
  1473.                 computer = !towho;
  1474.                 opponent = towho;
  1475.             }
  1476.             if (bothsides) {
  1477.                 computer = towho;
  1478.                 opponent = !towho;
  1479.             }
  1480.             Sdepth = 0;
  1481.               newgame = 0;
  1482.               drawn = 0;
  1483.           }
  1484.           
  1485.       if (mate || drawn)
  1486.           mainLoop();
  1487.       else {
  1488.         if (towho == white)
  1489.                   SetCursor(*ArrowCursor);
  1490.           else    SetCursor(&arrow);
  1491.           
  1492.  
  1493.           for (i=0; i<64; i++) {
  1494.               saveBoard[i] = board[i];
  1495.               saveColor[i] = color[i];
  1496.         }
  1497.  
  1498.           if (((towho == opponent) && !bothsides) || force)
  1499.                   InputCommand();
  1500.           else    SelectMove (towho, 1);
  1501.           
  1502.           if (!donotplay) {
  1503.               towho = !towho;
  1504.         } else donotplay = 0;
  1505.       }
  1506.     }
  1507. }
  1508.  
  1509.